{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import seaborn as sns\n",
    "import pandas as pd\n",
    "sns.set(font_scale=1.5)\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "from sklearn import linear_model\n",
    "from sklearn.linear_model import LinearRegression\n",
    "\n",
    "from sklearn.metrics import mean_squared_error\n",
    "from sklearn.metrics import mean_absolute_error\n",
    "from sklearn.pipeline import Pipeline\n",
    "from sklearn.preprocessing import PolynomialFeatures"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### P1: Understanding Alpha"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### P1A: Using Ridge instead of LinearRegression"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In HW3, we had you fit a model to predict the x-y relationship given below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "file1 = r'D:\\Programing\\python_projects\\machine_learning_algorithm\\data_set\\p1.csv'\n",
    "p1_data = pd.read_csv(file1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x28f6976d188>]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(p1_data[\"x\"], p1_data[\"y\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In particular, we had you create a new dataframe with 3 features: x, sin(x) and sin(5x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "featurized_p1_data = pd.DataFrame({\n",
    "    \"phi1\": p1_data[\"x\"],\n",
    "    \"phi2\": np.sin(p1_data[\"x\"]),\n",
    "    \"phi3\": np.sin(5 * p1_data[\"x\"])\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To understand how regularization works, let's now try using the `Ridge` module instead of `LinearRegression`. Recall that `Ridge` takes an `alpha` parameter that lets us control the complexity of our model.\n",
    "\n",
    "Let's start by using `alpha = 0`, which will make our model work exactly like `LinearRegression`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Ridge(alpha=0, copy_X=True, fit_intercept=True, max_iter=None,\n",
       "   normalize=False, random_state=None, solver='auto', tol=0.001)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p1_model_alpha0 = linear_model.Ridge(alpha=0)\n",
    "p1_model_alpha0.fit(featurized_p1_data, p1_data[\"y\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2. , 3. , 0.5])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p1_model_alpha0.coef_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Observe above that the coefficients are exactly the same that we found in hw3.\n",
    "\n",
    "Below:\n",
    "1. Fit a model `p1_model_alpha100` that has an alpha value of 100. \n",
    "2. Print out the coefficients of the model and compare them to the coefficients for `p1_model`\n",
    "3. Make a plot of the predictions made by `p1_model_alpha100` and compare them to the original data.\n",
    "\n",
    "You should see that the coefficients are slightly smaller and the fit is not quite as good."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Ridge(alpha=100, copy_X=True, fit_intercept=True, max_iter=None,\n",
       "   normalize=False, random_state=None, solver='auto', tol=0.001)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p1_model_alpha100 = linear_model.Ridge(alpha=100)\n",
    "p1_model_alpha100.fit(featurized_p1_data, p1_data['y'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([2.008366  , 2.09787207, 0.35873337])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p1_model_alpha100.coef_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x28f6b56bb08>]"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(p1_data[\"x\"], p1_data[\"y\"])\n",
    "plt.plot(p1_data[\"x\"], p1_model_alpha100.predict(featurized_p1_data))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now repeat the same exercise with alpha = 1000."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Ridge(alpha=1000, copy_X=True, fit_intercept=True, max_iter=None,\n",
       "   normalize=False, random_state=None, solver='auto', tol=0.001)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p1_model_alpha1000 = linear_model.Ridge(alpha=1000)\n",
    "p1_model_alpha1000.fit(featurized_p1_data, p1_data['y'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([1.93820735, 0.59244613, 0.09695011])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p1_model_alpha1000.coef_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<matplotlib.lines.Line2D at 0x28f6ba29388>]"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(p1_data[\"x\"], p1_data[\"y\"])\n",
    "plt.plot(p1_data[\"x\"], p1_model_alpha100.predict(featurized_p1_data))\n",
    "plt.plot(p1_data[\"x\"], p1_model_alpha1000.predict(featurized_p1_data))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You should see that the model has to spend much more of its \"budget\" on the linear coefficient, and isn't able to really capture much of the oscillating behavior."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### P1B: Understanding Objective Functions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To get a better understanding for how $\\alpha$ forces our parameters to be smaller, let's revisit the definition of our regularizaed model."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Recall that `Ridge` tries to minimize the sum of the mean squared error plus the squares of all the coefficients times alpha, i.e. $\\text{MSE} + \\alpha \\sum_{i=1}^n \\theta_i$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For example, if our coefficients are `[2, 3, 0.5]`, then the MSE is effectively zero. That is, you should get a value that is something like 10 to the -29th power."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.3979176456502124e-29"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mean_squared_error(p1_model_alpha0.predict(featurized_p1_data), p1_data[\"y\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If our coefficients are `[2, 3, 0.5]` and `alpha = 100`, then the objective function is $0 + 100 \\times (2^2 + 3^2 + 0.5^2) = 0$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1325.0"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sum(100 * [2 * 2 + 3 * 3 + 0.5 * 0.5])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Or using `p1_model_alpha0` directly:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1324.9999999999986"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sum(100 * p1_model_alpha0.coef_**2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below, compute the value of the objective function for alpha = 100 for `p1_model_alpha100`. Hint: The result should be approximately 856."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "856.3290835576983"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sum(100 * p1_model_alpha100.coef_**2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The gives us some insight into how `alpha` works. When we tell `p1_model_alpha100` to `fit` itself to the data, it has to minimize two things at once: The MSE and $\\alpha \\sum_{i=1}^n \\theta_i$. So when faced with a choice between `[2, 3, 0.5]` and `[2, 2.1, 0.36]`, it picks `[2, 2.1, 0.36]`. Even though `[2, 2.1, 0.36]` has worse MSE, it has better $\\alpha \\sum_{i=1}^n \\theta_i$."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Lastly, compute the value of the objective function for `p1_model_alpha1000` and `alpha = 1000`. You should get a value that is a little more than 4000."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4120.209862847307"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "mean_squared_error(p1_model_alpha1000.predict(featurized_p1_data),\n",
    "                   p1_data['y']) + np.sum(1000 * p1_model_alpha1000.coef_**2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### P2: Pipelines, Scaling, Regularization"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this problem, we'll explore how to use pipelines, scaling, and regularization."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### P2A: Understanding and Fitting Our Data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this homework, we'll be trying to fit Seattle house prices from 2014 and 2015. I originally got this data from Kaggle (https://www.kaggle.com/harlfoxem/housesalesprediction), but did some processing to remove some errors in the data (e.g. one house was incorrectly claimed to have 33 bedrooms)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "file2 = r'D:\\Programing\\python_projects\\machine_learning_algorithm\\data_set\\seattle_housing.csv'\n",
    "houses = pd.read_csv(file2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>id</th>\n",
       "      <th>date</th>\n",
       "      <th>price</th>\n",
       "      <th>bedrooms</th>\n",
       "      <th>bathrooms</th>\n",
       "      <th>sqft_living</th>\n",
       "      <th>sqft_lot</th>\n",
       "      <th>floors</th>\n",
       "      <th>waterfront</th>\n",
       "      <th>view</th>\n",
       "      <th>...</th>\n",
       "      <th>grade</th>\n",
       "      <th>sqft_above</th>\n",
       "      <th>sqft_basement</th>\n",
       "      <th>yr_built</th>\n",
       "      <th>yr_renovated</th>\n",
       "      <th>zipcode</th>\n",
       "      <th>lat</th>\n",
       "      <th>long</th>\n",
       "      <th>sqft_living15</th>\n",
       "      <th>sqft_lot15</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>7129300520</td>\n",
       "      <td>20141013T000000</td>\n",
       "      <td>221900</td>\n",
       "      <td>3</td>\n",
       "      <td>1.00</td>\n",
       "      <td>1180</td>\n",
       "      <td>5650</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>7</td>\n",
       "      <td>1180</td>\n",
       "      <td>0</td>\n",
       "      <td>1955</td>\n",
       "      <td>0</td>\n",
       "      <td>98178</td>\n",
       "      <td>47.5112</td>\n",
       "      <td>-122.257</td>\n",
       "      <td>1340</td>\n",
       "      <td>5650</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>6414100192</td>\n",
       "      <td>20141209T000000</td>\n",
       "      <td>538000</td>\n",
       "      <td>3</td>\n",
       "      <td>2.25</td>\n",
       "      <td>2570</td>\n",
       "      <td>7242</td>\n",
       "      <td>2.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>7</td>\n",
       "      <td>2170</td>\n",
       "      <td>400</td>\n",
       "      <td>1951</td>\n",
       "      <td>1991</td>\n",
       "      <td>98125</td>\n",
       "      <td>47.7210</td>\n",
       "      <td>-122.319</td>\n",
       "      <td>1690</td>\n",
       "      <td>7639</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>5631500400</td>\n",
       "      <td>20150225T000000</td>\n",
       "      <td>180000</td>\n",
       "      <td>2</td>\n",
       "      <td>1.00</td>\n",
       "      <td>770</td>\n",
       "      <td>10000</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>6</td>\n",
       "      <td>770</td>\n",
       "      <td>0</td>\n",
       "      <td>1933</td>\n",
       "      <td>0</td>\n",
       "      <td>98028</td>\n",
       "      <td>47.7379</td>\n",
       "      <td>-122.233</td>\n",
       "      <td>2720</td>\n",
       "      <td>8062</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2487200875</td>\n",
       "      <td>20141209T000000</td>\n",
       "      <td>604000</td>\n",
       "      <td>4</td>\n",
       "      <td>3.00</td>\n",
       "      <td>1960</td>\n",
       "      <td>5000</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>7</td>\n",
       "      <td>1050</td>\n",
       "      <td>910</td>\n",
       "      <td>1965</td>\n",
       "      <td>0</td>\n",
       "      <td>98136</td>\n",
       "      <td>47.5208</td>\n",
       "      <td>-122.393</td>\n",
       "      <td>1360</td>\n",
       "      <td>5000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>1954400510</td>\n",
       "      <td>20150218T000000</td>\n",
       "      <td>510000</td>\n",
       "      <td>3</td>\n",
       "      <td>2.00</td>\n",
       "      <td>1680</td>\n",
       "      <td>8080</td>\n",
       "      <td>1.0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>...</td>\n",
       "      <td>8</td>\n",
       "      <td>1680</td>\n",
       "      <td>0</td>\n",
       "      <td>1987</td>\n",
       "      <td>0</td>\n",
       "      <td>98074</td>\n",
       "      <td>47.6168</td>\n",
       "      <td>-122.045</td>\n",
       "      <td>1800</td>\n",
       "      <td>7503</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>5 rows × 21 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "           id             date   price  bedrooms  bathrooms  sqft_living  \\\n",
       "0  7129300520  20141013T000000  221900         3       1.00         1180   \n",
       "1  6414100192  20141209T000000  538000         3       2.25         2570   \n",
       "2  5631500400  20150225T000000  180000         2       1.00          770   \n",
       "3  2487200875  20141209T000000  604000         4       3.00         1960   \n",
       "4  1954400510  20150218T000000  510000         3       2.00         1680   \n",
       "\n",
       "   sqft_lot  floors  waterfront  view  ...  grade  sqft_above  sqft_basement  \\\n",
       "0      5650     1.0           0     0  ...      7        1180              0   \n",
       "1      7242     2.0           0     0  ...      7        2170            400   \n",
       "2     10000     1.0           0     0  ...      6         770              0   \n",
       "3      5000     1.0           0     0  ...      7        1050            910   \n",
       "4      8080     1.0           0     0  ...      8        1680              0   \n",
       "\n",
       "   yr_built  yr_renovated  zipcode      lat     long  sqft_living15  \\\n",
       "0      1955             0    98178  47.5112 -122.257           1340   \n",
       "1      1951          1991    98125  47.7210 -122.319           1690   \n",
       "2      1933             0    98028  47.7379 -122.233           2720   \n",
       "3      1965             0    98136  47.5208 -122.393           1360   \n",
       "4      1987             0    98074  47.6168 -122.045           1800   \n",
       "\n",
       "   sqft_lot15  \n",
       "0        5650  \n",
       "1        7639  \n",
       "2        8062  \n",
       "3        5000  \n",
       "4        7503  \n",
       "\n",
       "[5 rows x 21 columns]"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "houses.head(5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For example, the fourth house sold for 604,000 U.S. Dollars, has 3 bathrooms, and 1,960 square feet of living space (182 square meters)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We see that there are a number of different features we could use to predict the house price."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Index(['id', 'date', 'price', 'bedrooms', 'bathrooms', 'sqft_living',\n",
       "       'sqft_lot', 'floors', 'waterfront', 'view', 'condition', 'grade',\n",
       "       'sqft_above', 'sqft_basement', 'yr_built', 'yr_renovated', 'zipcode',\n",
       "       'lat', 'long', 'sqft_living15', 'sqft_lot15'],\n",
       "      dtype='object')"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "houses.columns"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In this problem, we will use the number of bedrooms, bathrooms, square feet of living space, square foot of the lot size, condition, and grade of the house. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "p2_features = [\n",
    "    'bedrooms', 'bathrooms', 'sqft_living', 'sqft_lot', 'condition', 'grade'\n",
    "]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "We do not take into account other important information like the part of the city in which the town is located. For example, houses near the city center are more likely to fetch a higher value. As a bonus exercise, you can try to include this additional information after completing this entier assignment."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Using what you know, fit a linear regression model called `p2a_model` to the entire available dataset. Use the `LinearRegression` module, not the `Ridge` module."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p2a_model = linear_model.LinearRegression()\n",
    "p2a_model.fit(houses[p2_features], houses['price'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now compute the predicted price of each house:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "price_predictions = p2a_model.predict(houses[p2_features])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below, we compute the root mean squared error (RMSE), which is just the square root of the mean squared error. If you did everything correctly, the value should be \\$206,445. This means that on average, we were somewhere around \\$200,000 off from the correct price in our predictions.\n",
    "\n",
    "In the following parts of this homework, we will try to do better, while also taking care to avoid overfitting."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "206445.61664480748"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sqrt(mean_squared_error(price_predictions, houses[\"price\"]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### P2B: Creating a Polynomial Model with Pipelines"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "One way that we can do better is to create new features which are polynomial combinations of our existing features. We did this in HW3.\n",
    "\n",
    "In this problem you will do this again, but now using sklearn pipelines.\n",
    "\n",
    "Using the lecture code as a guide, create and fit a model called `p2_poly2_model`. It should have two stages, the first of which is `PolynomialFeatures`, and the second of which is `LinearRegression`. Use a degree of 2 for your polynomial.\n",
    "\n",
    "Hint: See `diamond_poly_model` in the notebook for lecture 4."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Pipeline(memory=None,\n",
       "     steps=[('poly', PolynomialFeatures(degree=2, include_bias=True, interaction_only=False)), ('model', LinearRegression(copy_X=True, fit_intercept=False, n_jobs=1, normalize=False))])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p2_poly2_model = Pipeline([('poly', PolynomialFeatures(2)),\n",
    "                           ('model', LinearRegression(fit_intercept=False))])\n",
    "p2_poly2_model.fit(houses[p2_features], houses['price'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below, we compute price predictions and compute the RMSE for those predictions. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "poly2_price_predictions = p2_poly2_model.predict(houses[p2_features])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "189062.53010330888"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sqrt(mean_squared_error(poly2_price_predictions, houses[\"price\"]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Observe that the error is now lower. By creating new features, we now get better predictions."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below, repeat the same exercise but with a degree of 3. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Pipeline(memory=None,\n",
       "     steps=[('poly', PolynomialFeatures(degree=3, include_bias=True, interaction_only=False)), ('model', LinearRegression(copy_X=True, fit_intercept=False, n_jobs=1, normalize=False))])"
      ]
     },
     "execution_count": 28,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p2_poly3_model = Pipeline([('poly', PolynomialFeatures(3)),\n",
    "                           ('model', LinearRegression(fit_intercept=False))])\n",
    "p2_poly3_model.fit(houses[p2_features], houses['price'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "poly3_price_predictions = p2_poly3_model.predict(houses[p2_features])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "261582.41606501018"
      ]
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sqrt(mean_squared_error(poly3_price_predictions, houses[\"price\"]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Above, you should find that the RMSE for a degree 3 model is more than \\$260,000. That is, by adding additional features to use in fitting our model, we have somehow made our model worse.\n",
    "\n",
    "In theory, adding new features should never make our Linear Regression models worse (there are interesting mathematical reasons we have not covered in our course). However, our RMSE has gotten much worse!\n",
    "\n",
    "The reason is that the degree 3 polynomial results in values that are so large that your computer cannot store them precisely (see https://en.wikipedia.org/wiki/Round-off_error if you're curious).\n",
    "\n",
    "For example, the line below shows that one of our features is on the order of 10 to the 18th power. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.0739557477092424e+18"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.max(p2_poly3_model.named_steps[\"poly\"].transform(houses[p2_features]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the next section, we'll see how to avoid this problem."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### P2C: Using the StandardScaler"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "By rescaling the units of our original data so that each has mean 0 and variance 1, we can avoid the numerical precision errors we faced earlier."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import StandardScaler"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Using the lecture code as a guide, create and fit a model called `p2_scaled_poly2_model`. It should have three stages, the first of which is `StandardScaler`, the second of which is `PolynomialFeatures`, and the third of which is `LinearRegression`. Use a degree of 2 for your polynomial.\n",
    "\n",
    "Hint: See `degree_4_linear_regression_model` from the lecture 4 notebook for an example."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Pipeline(memory=None,\n",
       "     steps=[('scale', StandardScaler(copy=True, with_mean=True, with_std=True)), ('poly', PolynomialFeatures(degree=2, include_bias=True, interaction_only=False)), ('model', LinearRegression(copy_X=True, fit_intercept=False, n_jobs=1, normalize=False))])"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p2_scaled_poly2_model = Pipeline([('scale', StandardScaler()),\n",
    "                                  ('poly', PolynomialFeatures(2)),\n",
    "                                  ('model',\n",
    "                                   LinearRegression(fit_intercept=False))])\n",
    "p2_scaled_poly2_model.fit(houses[p2_features], houses['price'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below we compute predictions for your model, followed by the RMSE. If you did this right, the RMSE should be around \\$190,000."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "scaled_poly2_price_predictions = p2_scaled_poly2_model.predict(\n",
    "    houses[p2_features])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "189062.5301033082"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sqrt(mean_squared_error(scaled_poly2_price_predictions, houses[\"price\"]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that your `p2_poly2_model` from problem p2b also had an RMSE of approximately \\$190,000. In other words, scaling didn't help for the degree 2 model.\n",
    "\n",
    "However, we'll see that it helps a lot with a degree 3 polynomial. Below, create a model `p2_scaled_poly3_model` that is exactly the same as `p2_scaled_poly2_model`, but with degree 3."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Pipeline(memory=None,\n",
       "     steps=[('scale', StandardScaler(copy=True, with_mean=True, with_std=True)), ('poly', PolynomialFeatures(degree=3, include_bias=True, interaction_only=False)), ('mosel', LinearRegression(copy_X=True, fit_intercept=False, n_jobs=1, normalize=False))])"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p2_scaled_poly3_model = Pipeline([('scale', StandardScaler()),\n",
    "                                  ('poly', PolynomialFeatures(3)),\n",
    "                                  ('mosel',\n",
    "                                   LinearRegression(fit_intercept=False))])\n",
    "p2_scaled_poly3_model.fit(houses[p2_features], houses['price'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below, compute the RMSE for `p2_scaled_poly3_model`. You should get a value of approximately \\$185,000.\n",
    "\n",
    "This is much better than `p2_poly3_model`, which had had RMSE of approximately \\$260,000.\n",
    "\n",
    "Here, scaling made an enormous difference."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "scaled_poly3_price_predictions = p2_scaled_poly3_model.predict(\n",
    "    houses[p2_features])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "185358.45105851037"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sqrt(mean_squared_error(scaled_poly3_price_predictions, houses[\"price\"]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### P2D: Visualizing RMSE vs. Degree"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Similar to what we did part 2D of homework 3, we will create a plot of the RMSE vs. polynomial degree."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, we will split our data into a training, validation, and test set.\n",
    "\n",
    "We use `np.split` to create `house_training_data`, `house_validation_data`, and `house_test_data` with 16209, 2702, and 2702 data points, respectively.\n",
    "\n",
    "I picked these numbers so that the training set was 75% of the data, and the test and validation sets made up the remaining 25%."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "21456"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(houses)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "N_train = 16092\n",
    "N_validation = 16209 + 2682"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "house_training_data, house_validation_data, house_test_data = np.split(\n",
    "    houses, [N_train, N_validation])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Fill in the function `get_training_and_validation_rmse(degree)` so that it returns the RMSE for the training and validation sets for a model with the given polynomial degree.\n",
    "\n",
    "For example, `get_training_and_validation_rmse(4)` should return approximately `(181,000, 195,000)`.\n",
    "\n",
    "Your solution should look quite similar to problem 2d from the lecture 3 homework."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_training_and_validation_rmse(degree):\n",
    "    model = Pipeline([('scale', StandardScaler()),\n",
    "                      ('poly', PolynomialFeatures(degree)),\n",
    "                      ('model', LinearRegression(fit_intercept=False))])\n",
    "    model.fit(house_training_data[p2_features], house_training_data['price'])\n",
    "    trainning_predictions = model.predict(house_training_data[p2_features])\n",
    "    trainning_rmse = np.sqrt(\n",
    "        mean_squared_error(trainning_predictions, house_training_data['price']))\n",
    "    validation_predictions = model.predict(house_validation_data[p2_features])\n",
    "    validation_rmse = np.sqrt(\n",
    "        mean_squared_error(validation_predictions,\n",
    "                           house_validation_data['price']))\n",
    "    return trainning_rmse, validation_rmse"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(206718.11190302964, 207882.6838279295)"
      ]
     },
     "execution_count": 43,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "get_training_and_validation_rmse(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(189350.78040621636, 190324.26499855897)"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "get_training_and_validation_rmse(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(184863.82777276833, 190106.75690551553)"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "get_training_and_validation_rmse(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(181308.0007405249, 194575.13286059114)"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "get_training_and_validation_rmse(4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below, create a plot of the training and validation RMSE vs. the degree. For reference, feel free to look back at the code in the lecture 3 homework."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0x28f6bb24588>"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "rmses = np.array([get_training_and_validation_rmse(i) for i in range(6)])\n",
    "\n",
    "plt.plot(rmses[:, 0])\n",
    "plt.plot(rmses[:, 1])\n",
    "plt.legend(['training', 'validation'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Above, you should see that the training error goes down and down as the polynomial degree increases. However, the validation error starts going up at degree 3, and increases dramatically at degree 5.\n",
    "\n",
    "This means that we are severely overfitting once we hit degree 5.\n",
    "\n",
    "In the next problem, we'll see how we can use regularization to keep all the degree 5 features, but still avoid overfitting."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### P2E: Using the Validation Set to Select an Alpha"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below, create a function `get_regularized_training_and_validation_rmse(alpha)` that is exactly the same as `get_training_and_validation_rmse(degree)`, except that:\n",
    "\n",
    "1. It should take a parameter called `alpha` instead of `degree`.\n",
    "2. The pipeline should use a `PolynomialFeatures` with degree 5.\n",
    "3. It should use `linear_model.Ridge` instead of `linear_model.LinearRegression`. The alpha parameter for this Ridge model should be equal to the given parameter."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_regularized_training_and_validation_rmse(alpha):\n",
    "    model = Pipeline([('scale', StandardScaler()),\n",
    "                      ('poly', PolynomialFeatures(5)),\n",
    "                      ('model',\n",
    "                       linear_model.Ridge(fit_intercept=False, alpha=alpha))])\n",
    "    model.fit(house_training_data[p2_features], house_training_data['price'])\n",
    "    trainning_predictions = model.predict(house_training_data[p2_features])\n",
    "    trainning_rmse = np.sqrt(\n",
    "        mean_squared_error(trainning_predictions, house_training_data['price']))\n",
    "    validation_predictions = model.predict(house_validation_data[p2_features])\n",
    "    validation_rmse = np.sqrt(\n",
    "        mean_squared_error(validation_predictions,\n",
    "                           house_validation_data['price']))\n",
    "    return trainning_rmse, validation_rmse"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The code below will plot the training and validation RMSE for various alphas using your function. It will take a while to run, possibly a few minutes.\n",
    "\n",
    "If it's taking too long, change the 50 to a small number."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [],
   "source": [
    "alphas = 10**np.linspace(0, 8, 50)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [],
   "source": [
    "rmses = np.array(\n",
    "    [get_regularized_training_and_validation_rmse(alpha) for alpha in alphas])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Text(0, 0.5, 'RMSE')"
      ]
     },
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.semilogx(alphas, rmses[:, 0])\n",
    "plt.semilogx(alphas, rmses[:, 1])\n",
    "plt.legend([\"training\", \"validation\"])\n",
    "plt.xlabel('alpha')\n",
    "plt.ylabel('RMSE')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([21], dtype=int64),)"
      ]
     },
     "execution_count": 86,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#You can use the code below to find the index of the minimum validation error\n",
    "np.where(rmses[:, 1] == min(rmses[:, 1]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2682.6957952797247"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "alphas[21]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Some questions to ponder:\n",
    "\n",
    "1. What is the best alpha to choose?\n",
    "2. Are the models with large alpha (right side of the graph) high complexity or low complexity?\n",
    "3. What part of the plot shows overfitting?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### P2F:  Performance on the Test Set"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Based on your plot from problem P2E, train a model called `p2f_model` with the optimal alpha on `house_training_data`, then compute the RMSE on the test set in `house_test_data`.\n",
    "\n",
    "Your result should be less than \\$210,000."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Pipeline(memory=None,\n",
       "     steps=[('scale', StandardScaler(copy=True, with_mean=True, with_std=True)), ('poly', PolynomialFeatures(degree=5, include_bias=True, interaction_only=False)), ('model', Ridge(alpha=2682, copy_X=True, fit_intercept=False, max_iter=None,\n",
       "   normalize=False, random_state=None, solver='auto', tol=0.001))])"
      ]
     },
     "execution_count": 88,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p2f_model = model = Pipeline([('scale', StandardScaler()),\n",
    "                              ('poly', PolynomialFeatures(5)),\n",
    "                              ('model',\n",
    "                               linear_model.Ridge(fit_intercept=False,\n",
    "                                                  alpha=2682))])\n",
    "p2f_model.fit(house_training_data[p2_features], house_training_data['price'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "205080.99506417307"
      ]
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sqrt(\n",
    "    mean_squared_error(p2f_model.predict(house_test_data[p2_features]),\n",
    "                       house_test_data[\"price\"]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Very important:** We managed to achieve this level of error without ever using the test data in any way. You'll see it's roughly as good as we got on the training set. Not bad! We have confidence that our model should generalize to other data from the same distribution. That is, if we pick a Seattle house at random from 2015, we would expect to get RMSE of less than \\$210,000. \n",
    "\n",
    "In theory, we could try adjusting the alpha to get better test error. In practice, this would be an incredibly bad idea. In effect, we would be fitting our alpha to the test data. Since the goal of our model is to build something that will work for future prediction, we would have no confidence it would work in the real world.\n",
    "\n",
    "*Note:* An RMSE of \\$210,000 is much better than random guessing, but there is still a lot more work to do to get the error lower. Taking into things like the neighborhood a house belongs to would help a lot. We leave this as an exercise for the especially interested student."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### P2G: Using RidgeCV"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In problem P2F, we found the optimal alpha by using a plot of the error on a validation set.\n",
    "\n",
    "An alternate approach is to use `RidgeCV`, which will automatically find the optimal `alpha` using only the validation set.\n",
    "\n",
    "Create a model `p2g_model` that uses `RidgeCV`. For the alphas parameter, use `10**np.linspace(0, 8, 50)`.\n",
    "\n",
    "This will probably take a while to run, possibly several minutes."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Pipeline(memory=None,\n",
       "     steps=[('scale', StandardScaler(copy=True, with_mean=True, with_std=True)), ('poly', PolynomialFeatures(degree=5, include_bias=True, interaction_only=False)), ('model', RidgeCV(alphas=array([1.00000e+00, 1.45635e+00, 2.12095e+00, 3.08884e+00, 4.49843e+00,\n",
       "       6.55129e+00, 9.54095e+00, 1.38950e+01...one, fit_intercept=False, gcv_mode=None, normalize=False,\n",
       "    scoring=None, store_cv_values=False))])"
      ]
     },
     "execution_count": 93,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p2g_model = Pipeline([('scale', StandardScaler()),\n",
    "                      ('poly', PolynomialFeatures(5)),\n",
    "                      ('model',\n",
    "                       linear_model.RidgeCV(fit_intercept=False,\n",
    "                                            alphas=(10**np.linspace(0, 8,\n",
    "                                                                    50))))])\n",
    "p2g_model.fit(house_training_data[p2_features], house_training_data['price'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "281.1768697974228"
      ]
     },
     "execution_count": 95,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p2g_model.named_steps['model'].alpha_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Above, we see that RidgeCV picks an alpha that is not the same as the one that you picked using a validation set."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below, we can evaluate the performance of the resulting model. You should see that the RMSE is pretty close to what you got in problem p2f."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "199507.994142042"
      ]
     },
     "execution_count": 97,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sqrt(\n",
    "    mean_squared_error(p2g_model.predict(house_test_data[p2_features]),\n",
    "                       house_test_data[\"price\"]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Important note:** `RidgeCV` was able to select a good alpha without using a special validation set. That is, it picked the alpha using ONLY the traiining set.\n",
    "\n",
    "The technique that `RidgeCV` uses is called \"cross validation\", and is described in lecture 4. We will not discuss the details of cross validation further in this homework."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Caveat:** There is a subtle issue with the way we used RidgeCV. In particular, the StandardScaler scales all of the data before passing it to RidgeCV. Ideally, we'd separately scale the data for each cross validation fold. This is a pretty advanced topic, so we will not discuss this in our course."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Takeaway:** In real world projects, you're welcome to use the approach from `p2f_model` or from `p2g_model`.\n",
    "\n",
    "p2f_model: Set aside a special validation set and test set. Use training set to fit the parameters of your ridge model. Use the validation set to fit the hyperparameters (in this case, alpha). Use the test set to evaluate performance at the very end. \n",
    "\n",
    "p2g_model: Set aside a special test set. Use the cross-validation technique to fit the parameters and hyperparamters using the training data. Use the test set to evalute performance at the very end.\n",
    "\n",
    "Both approaches are valid, but the p2g_model style is more common in the real world.\n",
    "\n",
    "**One last warning:** It is very important to avoid using the test data in any way whatsoever! You should not use the test data to fit paramters or hyperparamters."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Bonus Problem P2H: Lasso"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Recall from lecture that there is an alternate to Ridge regression called LASSO regression. The difference in outcome is that LASSO models have many zero paramters.\n",
    "\n",
    "Let's see it in action. Note that LASSO models are generally more numerically difficult to fit, so you may see several warnings appear about convergence. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Programing\\Anaconda3\\envs\\ml_env\\lib\\site-packages\\sklearn\\linear_model\\coordinate_descent.py:1094: DataConversionWarning: A column-vector y was passed when a 1d array was expected. Please change the shape of y to (n_samples, ), for example using ravel().\n",
      "  y = column_or_1d(y, warn=True)\n",
      "D:\\Programing\\Anaconda3\\envs\\ml_env\\lib\\site-packages\\sklearn\\linear_model\\coordinate_descent.py:491: ConvergenceWarning: Objective did not converge. You might want to increase the number of iterations. Fitting data with very small alpha may cause precision problems.\n",
      "  ConvergenceWarning)\n",
      "D:\\Programing\\Anaconda3\\envs\\ml_env\\lib\\site-packages\\sklearn\\linear_model\\coordinate_descent.py:491: ConvergenceWarning: Objective did not converge. You might want to increase the number of iterations. Fitting data with very small alpha may cause precision problems.\n",
      "  ConvergenceWarning)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "Pipeline(memory=None,\n",
       "     steps=[('scale', StandardScaler(copy=True, with_mean=True, with_std=True)), ('poly', PolynomialFeatures(degree=5, include_bias=True, interaction_only=False)), ('model', LassoCV(alphas=array([1.00000e+00, 1.45635e+00, 2.12095e+00, 3.08884e+00, 4.49843e+00,\n",
       "       6.55129e+00, 9.54095e+00, 1.38950e+01...alse,\n",
       "    precompute='auto', random_state=None, selection='cyclic', tol=0.0001,\n",
       "    verbose=False))])"
      ]
     },
     "execution_count": 103,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p2h_model = Pipeline([('scale', StandardScaler()),\n",
    "                      ('poly', PolynomialFeatures(degree=5)),\n",
    "                      ('model',\n",
    "                       linear_model.LassoCV(alphas=10**np.linspace(0, 8, 50),\n",
    "                                            fit_intercept=False))])\n",
    "p2h_model.fit(house_training_data[p2_features], house_training_data[[\"price\"]])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You'll see the RMSE of the resulting LASSO model is similar to the RidgeCV RMSE from problem p2g."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "189661.15862046462"
      ]
     },
     "execution_count": 104,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.sqrt(\n",
    "    mean_squared_error(p2h_model.predict(house_test_data[p2_features]),\n",
    "                       house_test_data[\"price\"]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The big difference is that the coefficents of the p2h_model are almost all zero, whereas with p2g_model, none of them are."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 3.38831354e+05, -6.92128440e+03, -1.65541976e+04,  8.04259986e+04,\n",
       "       -5.39149050e+04, -1.14373719e+04,  8.81106576e+04,  3.30468073e+04,\n",
       "       -2.35601253e+03, -1.09725110e+04,  8.49679646e+03,  1.20384165e+03,\n",
       "        1.21124360e+03,  3.64975524e+04, -7.84778196e+03,  1.44098545e+04,\n",
       "        2.24101680e+04, -1.01119811e+04,  1.93569597e+04, -1.59922456e+04,\n",
       "        8.70344034e+03,  2.97385684e+03,  5.91291504e+04, -1.43121329e+04,\n",
       "       -2.59796632e+04,  1.55010980e+05,  9.33354091e+03,  4.37937773e+04,\n",
       "       -3.05740069e+03, -1.46131095e+03,  1.39024271e+03, -2.49638129e+03,\n",
       "       -1.41827137e+03,  1.46637831e+04, -2.32044133e+03, -1.35316201e+04,\n",
       "        4.81214009e+03,  2.60289511e+03, -1.33664595e+03,  8.06319793e+03,\n",
       "        1.35002374e+04, -8.06395204e+03, -1.50453762e+04,  5.61425803e+03,\n",
       "       -6.23530008e+03,  8.24064989e+03, -1.63351136e+04,  3.74596324e+03,\n",
       "        1.23540444e+04, -4.55031140e+02,  4.85531734e+03, -1.67820015e+04,\n",
       "        3.37726886e+03,  3.35564408e+04,  2.06144575e+03, -2.84746974e+03,\n",
       "        2.77266541e+03, -6.01321194e+03,  5.32703098e+03, -9.46384327e+03,\n",
       "        1.03151129e+03,  1.98257672e+03,  3.20875504e+03, -5.94104801e+03,\n",
       "        5.35861488e+03, -1.98856084e+04, -5.09909300e+03, -1.63018752e+03,\n",
       "       -2.17287148e+03, -8.36730919e+03, -1.30670740e+04,  3.61432898e+04,\n",
       "        1.25869445e+04, -3.69855531e+03, -1.47707980e+04, -1.06040652e+04,\n",
       "        1.03674112e+04, -2.96582391e+04,  3.16380393e+03, -1.56388831e+04,\n",
       "        4.32692900e+04,  1.81444014e+04,  4.95247917e+03, -8.35475660e+02,\n",
       "       -1.31876093e+03,  1.26721943e+03, -1.65358975e+03, -6.46033067e+03,\n",
       "       -2.50840493e+03,  1.71457642e+03, -1.60542036e+03,  4.44681251e+03,\n",
       "        3.07099863e+03,  5.59078681e+02,  7.38332475e+03, -5.57782500e+03,\n",
       "        7.47674108e+03,  2.26211221e+03, -2.04783190e+03, -3.04769304e+03,\n",
       "        1.13151454e+03, -7.35374211e+02, -5.36581366e+03,  7.41660025e+03,\n",
       "       -2.75948468e+03, -6.84731219e+03,  2.48333583e+03,  1.43867451e+02,\n",
       "        8.37875708e+02, -3.33308512e+03,  4.95376522e+03, -2.30181873e+03,\n",
       "       -9.78662544e+03,  2.93953767e+03, -2.62726338e+03,  9.21627978e+01,\n",
       "        8.45197507e+03,  3.92166285e+03, -1.29646465e+04, -1.90042321e+03,\n",
       "       -9.36793932e+03, -1.41879911e+03, -5.25040582e+02,  8.64512737e+03,\n",
       "       -2.65014486e+03,  2.00849361e+03, -4.75529143e+02,  1.31801549e+03,\n",
       "        2.38904134e+03, -1.64200834e+03, -1.87132015e+03,  1.06214914e+04,\n",
       "        5.51422989e+03, -6.26943505e+03, -5.04547554e+03, -9.42315109e+02,\n",
       "       -2.05683043e+02,  2.12613273e+03,  5.11489367e+03, -4.72094242e+01,\n",
       "       -2.45449990e+03,  6.26738574e+03,  7.56206208e+01, -8.43748956e+03,\n",
       "       -5.59211834e+03, -9.34242712e+03, -6.10697642e+03,  6.23761868e+03,\n",
       "       -1.11391220e+04,  1.25304809e+04,  9.41616707e+03, -6.24586660e+03,\n",
       "       -1.75052760e+03, -3.58168731e+03,  5.52476824e+03,  1.83722265e+02,\n",
       "        3.71193419e+03, -1.27216442e+03,  1.18709748e+04, -3.15329387e+03,\n",
       "        3.72877887e+03, -1.98132642e+03,  5.03434726e+03,  7.15864413e+03,\n",
       "        4.75707255e+02, -3.25221715e+03,  1.60097226e+03, -3.37705645e+03,\n",
       "        8.27851318e+02,  8.54726367e+02,  2.15957952e+03, -3.24999619e+03,\n",
       "       -8.07564016e+03,  7.30180417e+03,  8.14713838e+01, -4.46789949e+03,\n",
       "        5.17130331e+03,  1.04660847e+03,  7.74185074e+03,  4.90111348e+03,\n",
       "       -1.05232752e+04,  1.64298723e+02,  8.13810982e+03, -1.14348245e+03,\n",
       "       -8.51281696e+03,  1.46796874e+03,  3.21111653e+02, -1.85538023e+03,\n",
       "       -6.50035974e+02, -5.62116366e+03,  9.57834633e+01, -1.78985924e+03,\n",
       "       -6.42200865e+03, -1.24325477e+02,  4.19383108e+03,  1.34160108e+03,\n",
       "        3.14485660e+03,  2.50729962e+00,  1.80031915e+04,  3.01097987e+03,\n",
       "        2.59210567e+03, -2.23615199e+03,  1.90317524e+03, -1.06075577e+03,\n",
       "       -1.03516776e+03, -2.42264544e+04,  2.33522259e+02,  1.89597750e+03,\n",
       "       -3.47402587e+03, -4.22805168e+03,  6.05128284e+01, -3.29855881e+02,\n",
       "        1.13914366e+03, -1.98014687e+02,  5.60897243e+02, -1.23205743e+02,\n",
       "       -8.95495449e+02,  3.20192491e+03,  4.00544924e+02,  1.50853991e-01,\n",
       "       -4.50967754e+03, -3.05456381e+03,  4.26134964e+02,  6.16207765e+02,\n",
       "        3.06911956e+03,  1.14255642e+03, -1.12487671e+03,  2.37705283e+03,\n",
       "        2.42265029e+03, -1.99072948e+03,  3.87315406e+02,  4.16282559e+02,\n",
       "        2.07384599e+03, -4.07997601e+03, -2.93741977e+03, -4.65027894e+02,\n",
       "       -1.12033747e+04,  8.31491029e+02, -4.88730560e+03,  1.25002715e+04,\n",
       "        1.92414923e+03,  3.16941493e+03,  9.81474639e+02,  1.87584843e+03,\n",
       "        7.76386197e+03,  2.90238293e+03,  7.26177804e+03, -2.53144224e+02,\n",
       "       -9.78497047e+01, -9.18569425e+03, -7.01981970e+02,  5.18881521e+03,\n",
       "       -3.26349232e+03, -5.80987013e+03,  4.33762127e+02,  3.48817531e+03,\n",
       "        4.37748066e+02, -7.14460154e+02, -2.35731493e+03,  2.82650121e+03,\n",
       "       -2.09242523e+03,  1.60332759e+03,  2.26263609e+02, -5.30068119e+03,\n",
       "        1.10802334e+02, -4.42232445e+03,  1.64652883e+03, -4.64139248e+03,\n",
       "       -3.51708229e+03,  2.32504388e+03,  6.02190068e+03,  9.55652982e+03,\n",
       "        1.09309606e+04,  9.53458229e+03, -1.40794843e+04,  8.66681938e+02,\n",
       "        9.46906526e+02, -6.04239964e+03, -1.76890623e+03, -6.04847511e+03,\n",
       "       -4.14373849e+03, -3.33417023e+02, -3.68388713e+03,  7.29246000e+03,\n",
       "       -2.39292233e+03, -6.33421438e+03, -3.17349502e+02,  9.94743696e+03,\n",
       "        1.06151691e+04, -8.11824948e+03,  4.45783005e+03,  2.99946326e+02,\n",
       "       -2.90544359e+03,  1.21363883e+03,  4.07649018e+03,  2.98907807e+03,\n",
       "        6.10724195e+03, -2.73235126e+03,  3.09193129e+03, -7.90585250e+03,\n",
       "       -3.25588046e+02,  1.25688667e+03,  1.35796524e+02, -5.65746287e+02,\n",
       "       -5.39761344e+03,  2.27292061e+02, -9.53073308e+03, -5.39188873e+03,\n",
       "       -2.64902791e+03, -7.44632525e+03,  5.18606844e+03,  4.68538000e+02,\n",
       "        2.79925965e+03,  3.43974094e+03,  3.76517552e+03,  2.30156682e+03,\n",
       "       -2.66436946e+03,  1.41059899e+03, -1.96933201e+03,  1.07305627e+04,\n",
       "        4.43376669e+03,  7.83667877e+01, -1.47424784e+03, -8.17655131e+02,\n",
       "        1.26309140e+03,  3.28121383e+03, -6.10663702e+02, -2.54841349e+03,\n",
       "       -1.22364180e+04, -1.71909518e+03, -2.62819845e+03,  1.20669334e+03,\n",
       "        8.62321598e+02,  4.15690654e+03,  2.41081096e+03, -3.38446203e+03,\n",
       "        4.28316205e+02, -2.91814061e+03,  2.82956505e+03,  1.78665468e+02,\n",
       "       -2.22933630e+03,  5.21900884e+03, -3.14753182e+03, -8.98961923e+03,\n",
       "       -5.27321861e+02, -4.81315406e+02, -7.48381417e+03,  2.50665167e+03,\n",
       "        4.38821862e+03,  6.62342298e+03,  4.41057435e+03, -3.39302271e+03,\n",
       "       -5.18036195e+03,  1.25657783e+04,  9.87586231e+03,  3.65537889e+03,\n",
       "        3.17339719e+03, -1.15446158e+03, -7.52059795e+03,  2.60898525e+03,\n",
       "       -8.96228442e+03, -1.09542666e+03,  3.30488178e+03, -2.56382654e+03,\n",
       "       -9.52555979e+03, -4.44705183e+03, -1.17537656e+02, -2.92189124e+03,\n",
       "       -6.46934512e+03, -4.47653515e+03,  1.62673919e+03,  5.93223789e+02,\n",
       "        2.60784719e+03, -6.55546421e+03,  2.73445497e+02, -2.69047452e+02,\n",
       "        5.72727581e+03,  2.38470997e+02,  4.42533488e+03, -6.91518269e+03,\n",
       "       -1.22996962e+04, -1.95309596e+01, -6.10118438e+03,  8.25745559e+02,\n",
       "       -1.23629955e+03, -4.54427482e+03,  3.23492569e+03, -6.96908331e+02,\n",
       "        2.01693367e+03,  5.14721812e+02,  1.21022202e+04,  2.67079312e+02,\n",
       "        1.68482131e+02,  1.50304522e+02,  4.50193181e+02, -3.45680776e+03,\n",
       "        1.51394161e+03,  3.85125800e+03,  3.13127155e+03,  8.22132552e+03,\n",
       "       -2.40430138e+03,  8.51643486e+01,  1.64739750e+03, -3.90903485e+03,\n",
       "        1.95708287e+03, -4.02314651e+03, -3.49684820e+02,  3.72410135e+01,\n",
       "       -1.70883545e+03,  7.45551508e+02,  7.71904134e+01, -1.17264495e+03,\n",
       "       -1.90785188e+03, -1.00914463e+03,  6.49366670e+03,  1.26680719e+03,\n",
       "       -4.54152936e+02,  3.61317841e+03,  2.92734518e+02, -3.08315554e+03,\n",
       "        7.64616479e+03,  1.65319379e+03, -2.95072830e+03,  3.41781074e+03,\n",
       "        7.53124655e+02,  4.68910627e+02, -8.94783781e+01, -4.28423063e+02,\n",
       "        5.96065814e+02, -1.96588044e+03, -2.97959488e+03, -2.88612240e+03,\n",
       "        4.82050787e+03,  9.16065441e+03, -1.14174432e+04, -1.80823537e+03,\n",
       "       -2.24794250e+03,  1.87589284e+03, -3.33462406e+03, -9.66604450e+02,\n",
       "       -2.56716905e+03, -3.66328841e+01, -1.92451178e+02, -6.60794083e+01,\n",
       "       -2.35389394e+03,  1.15381690e+02,  3.91798601e+01,  8.69145474e+02,\n",
       "       -1.73810131e+03,  5.95397074e+03,  3.35505565e+02,  7.00752317e+00,\n",
       "       -3.06007093e+03,  1.99662505e+03, -1.92162912e+03,  3.69394421e+03,\n",
       "       -6.57172064e+03, -1.40961789e+03, -1.03030564e+03,  7.88920843e+02,\n",
       "       -1.82190380e+03,  1.81960839e+03])"
      ]
     },
     "execution_count": 105,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p2g_model.named_steps['model'].coef_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 4.53576618e+05, -0.00000000e+00,  0.00000000e+00,  7.07149201e+04,\n",
       "       -0.00000000e+00,  4.97772289e+03,  9.01448762e+04,  6.98872719e+03,\n",
       "        0.00000000e+00,  0.00000000e+00, -0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  1.21285916e+04,  0.00000000e+00, -0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  1.82085213e+03, -0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00, -0.00000000e+00,\n",
       "       -0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  2.18191210e+04,\n",
       "        0.00000000e+00, -0.00000000e+00,  0.00000000e+00, -0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00, -0.00000000e+00,  0.00000000e+00,\n",
       "       -0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "       -0.00000000e+00,  0.00000000e+00,  0.00000000e+00, -0.00000000e+00,\n",
       "       -0.00000000e+00, -0.00000000e+00, -0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00, -0.00000000e+00,\n",
       "        0.00000000e+00,  7.65242793e+03,  0.00000000e+00, -0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00, -0.00000000e+00, -0.00000000e+00,\n",
       "       -0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        3.87880228e+03, -0.00000000e+00,  6.12828262e+02,  0.00000000e+00,\n",
       "        0.00000000e+00, -0.00000000e+00, -0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  4.61480110e+01,  0.00000000e+00,\n",
       "       -0.00000000e+00, -0.00000000e+00,  0.00000000e+00, -0.00000000e+00,\n",
       "        3.91999670e+03,  0.00000000e+00,  3.14494281e+03,  3.95908960e+03,\n",
       "       -2.08914762e+02, -0.00000000e+00, -0.00000000e+00, -0.00000000e+00,\n",
       "       -0.00000000e+00,  1.32835700e+03, -0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "       -0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "       -0.00000000e+00, -0.00000000e+00, -0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00, -0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00, -0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00, -0.00000000e+00, -0.00000000e+00,\n",
       "        0.00000000e+00, -0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00, -0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00, -0.00000000e+00, -0.00000000e+00, -0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00, -1.83014000e+02, -0.00000000e+00,\n",
       "        0.00000000e+00, -0.00000000e+00, -0.00000000e+00, -0.00000000e+00,\n",
       "       -0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00, -0.00000000e+00, -0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00, -0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00, -0.00000000e+00, -0.00000000e+00,\n",
       "       -0.00000000e+00,  0.00000000e+00,  0.00000000e+00, -0.00000000e+00,\n",
       "       -2.91459493e+02,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "       -0.00000000e+00, -0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00, -3.35373787e+01, -0.00000000e+00,  0.00000000e+00,\n",
       "       -0.00000000e+00, -0.00000000e+00, -0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00, -0.00000000e+00,\n",
       "       -3.05833109e+03,  1.32109391e+02,  2.24483236e+02,  1.10904832e+03,\n",
       "       -0.00000000e+00, -0.00000000e+00,  0.00000000e+00,  2.33510296e+03,\n",
       "        0.00000000e+00, -3.72566527e+01,  0.00000000e+00,  0.00000000e+00,\n",
       "       -0.00000000e+00, -0.00000000e+00, -0.00000000e+00,  1.31358087e+03,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00, -6.62265135e+00,\n",
       "        0.00000000e+00, -8.14737794e-01,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00, -1.05278598e+03, -0.00000000e+00, -0.00000000e+00,\n",
       "       -2.51811680e+03,  2.23414928e+03,  3.71845670e+03,  0.00000000e+00,\n",
       "        8.06642046e+02,  0.00000000e+00,  9.55738854e+00, -0.00000000e+00,\n",
       "        1.60463888e+02, -5.83313133e+01,  0.00000000e+00,  0.00000000e+00,\n",
       "       -0.00000000e+00,  0.00000000e+00,  0.00000000e+00, -0.00000000e+00,\n",
       "       -0.00000000e+00, -5.15754929e+02,  0.00000000e+00, -0.00000000e+00,\n",
       "       -0.00000000e+00,  1.52009835e+02,  0.00000000e+00,  0.00000000e+00,\n",
       "       -2.73295147e+02,  0.00000000e+00,  6.74572504e+02, -0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00, -0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "       -0.00000000e+00, -0.00000000e+00,  0.00000000e+00, -0.00000000e+00,\n",
       "       -0.00000000e+00,  0.00000000e+00, -3.29694191e+01,  0.00000000e+00,\n",
       "       -0.00000000e+00, -0.00000000e+00,  0.00000000e+00, -0.00000000e+00,\n",
       "        0.00000000e+00, -0.00000000e+00, -0.00000000e+00,  0.00000000e+00,\n",
       "       -5.81161026e+00, -0.00000000e+00, -1.53256781e+02,  0.00000000e+00,\n",
       "       -0.00000000e+00,  0.00000000e+00, -7.43322626e+01,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00, -2.58532843e+02,  0.00000000e+00,\n",
       "        0.00000000e+00,  3.85595163e+02, -1.99828573e+02,  4.38846771e+02,\n",
       "        0.00000000e+00,  8.76334492e+01, -0.00000000e+00,  0.00000000e+00,\n",
       "       -0.00000000e+00,  0.00000000e+00, -0.00000000e+00,  0.00000000e+00,\n",
       "       -0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00, -0.00000000e+00,  0.00000000e+00,\n",
       "       -0.00000000e+00,  0.00000000e+00, -0.00000000e+00,  5.91300548e+01,\n",
       "       -0.00000000e+00,  0.00000000e+00, -0.00000000e+00, -0.00000000e+00,\n",
       "        0.00000000e+00, -0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "       -0.00000000e+00, -2.61431767e+02, -0.00000000e+00,  0.00000000e+00,\n",
       "       -0.00000000e+00, -0.00000000e+00, -0.00000000e+00, -0.00000000e+00,\n",
       "       -0.00000000e+00,  0.00000000e+00,  0.00000000e+00, -4.88456027e+01,\n",
       "       -0.00000000e+00, -0.00000000e+00, -0.00000000e+00, -0.00000000e+00,\n",
       "        0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  8.35942232e+00, -1.34798712e+01,  1.60459320e+01,\n",
       "       -0.00000000e+00, -0.00000000e+00,  0.00000000e+00,  0.00000000e+00,\n",
       "       -0.00000000e+00, -0.00000000e+00,  0.00000000e+00, -6.63935688e+02,\n",
       "        2.98788117e+02,  0.00000000e+00,  8.24454429e+02, -2.27912277e+02,\n",
       "       -7.97902571e+01, -0.00000000e+00, -8.07235943e+02, -0.00000000e+00,\n",
       "       -1.12445985e+01,  3.48192561e+02, -0.00000000e+00,  0.00000000e+00,\n",
       "       -0.00000000e+00,  2.75605168e+02, -4.76959312e+02, -0.00000000e+00,\n",
       "       -0.00000000e+00, -0.00000000e+00, -1.49611178e+02,  0.00000000e+00,\n",
       "       -1.24739794e+02, -0.00000000e+00, -0.00000000e+00,  9.07620449e+01,\n",
       "       -0.00000000e+00, -0.00000000e+00, -0.00000000e+00, -0.00000000e+00,\n",
       "       -2.20157278e+02, -1.69569831e+01, -0.00000000e+00, -0.00000000e+00,\n",
       "       -0.00000000e+00, -0.00000000e+00, -0.00000000e+00, -1.39513356e+02,\n",
       "       -0.00000000e+00, -0.00000000e+00, -0.00000000e+00, -0.00000000e+00,\n",
       "       -0.00000000e+00, -0.00000000e+00, -0.00000000e+00,  6.48594213e+01,\n",
       "       -0.00000000e+00, -0.00000000e+00, -0.00000000e+00, -0.00000000e+00,\n",
       "       -0.00000000e+00, -5.65527077e+01,  0.00000000e+00,  4.39091947e+01,\n",
       "       -0.00000000e+00, -0.00000000e+00, -0.00000000e+00, -0.00000000e+00,\n",
       "       -0.00000000e+00, -0.00000000e+00, -1.62131234e+02,  5.53862466e+00,\n",
       "       -0.00000000e+00, -6.84779466e+00, -0.00000000e+00,  0.00000000e+00,\n",
       "       -0.00000000e+00, -0.00000000e+00, -0.00000000e+00, -0.00000000e+00,\n",
       "       -0.00000000e+00,  9.87993952e+01, -0.00000000e+00, -0.00000000e+00,\n",
       "       -0.00000000e+00, -2.10261712e+01, -1.12732061e+02,  0.00000000e+00,\n",
       "       -6.32134028e+02,  2.64384460e+02,  1.55455766e+02, -5.82639769e+02,\n",
       "        0.00000000e+00, -9.33861608e+01,  0.00000000e+00,  1.91859288e+01,\n",
       "       -9.90518386e+01,  0.00000000e+00,  3.63101249e+02, -1.14198087e+03,\n",
       "       -0.00000000e+00,  0.00000000e+00,  0.00000000e+00, -0.00000000e+00,\n",
       "        1.46389422e+03,  0.00000000e+00,  1.48254323e+00,  1.00199123e+02,\n",
       "       -5.11898792e+00,  0.00000000e+00,  0.00000000e+00,  1.56317497e+02,\n",
       "       -0.00000000e+00, -0.00000000e+00, -0.00000000e+00,  0.00000000e+00,\n",
       "        2.14532431e+03,  0.00000000e+00, -0.00000000e+00,  0.00000000e+00,\n",
       "        0.00000000e+00,  2.80408316e-01, -3.90256601e+00, -1.53144599e-01,\n",
       "        7.71882487e+01, -1.95901272e+01,  7.18476890e+00, -0.00000000e+00,\n",
       "       -2.98082295e+02,  1.33109749e+02,  0.00000000e+00, -7.78357902e+02,\n",
       "       -0.00000000e+00, -0.00000000e+00, -1.26875669e+03, -0.00000000e+00,\n",
       "        1.59341614e+02,  5.39151328e+02, -0.00000000e+00, -4.91317480e+02,\n",
       "       -3.15774678e+02,  5.96208117e-01])"
      ]
     },
     "execution_count": 106,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "p2h_model.named_steps['model'].coef_"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To understand what features each coefficient corresponds to, we can use the `get_feature_names` function of the `PolynomialFeatures` object."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['1',\n",
       " 'bedrooms',\n",
       " 'bathrooms',\n",
       " 'sqft_living',\n",
       " 'sqft_lot',\n",
       " 'condition',\n",
       " 'grade',\n",
       " 'bedrooms^2',\n",
       " 'bedrooms bathrooms',\n",
       " 'bedrooms sqft_living',\n",
       " 'bedrooms sqft_lot',\n",
       " 'bedrooms condition',\n",
       " 'bedrooms grade',\n",
       " 'bathrooms^2',\n",
       " 'bathrooms sqft_living',\n",
       " 'bathrooms sqft_lot',\n",
       " 'bathrooms condition',\n",
       " 'bathrooms grade',\n",
       " 'sqft_living^2',\n",
       " 'sqft_living sqft_lot',\n",
       " 'sqft_living condition',\n",
       " 'sqft_living grade',\n",
       " 'sqft_lot^2',\n",
       " 'sqft_lot condition',\n",
       " 'sqft_lot grade',\n",
       " 'condition^2',\n",
       " 'condition grade',\n",
       " 'grade^2',\n",
       " 'bedrooms^3',\n",
       " 'bedrooms^2 bathrooms',\n",
       " 'bedrooms^2 sqft_living',\n",
       " 'bedrooms^2 sqft_lot',\n",
       " 'bedrooms^2 condition',\n",
       " 'bedrooms^2 grade',\n",
       " 'bedrooms bathrooms^2',\n",
       " 'bedrooms bathrooms sqft_living',\n",
       " 'bedrooms bathrooms sqft_lot',\n",
       " 'bedrooms bathrooms condition',\n",
       " 'bedrooms bathrooms grade',\n",
       " 'bedrooms sqft_living^2',\n",
       " 'bedrooms sqft_living sqft_lot',\n",
       " 'bedrooms sqft_living condition',\n",
       " 'bedrooms sqft_living grade',\n",
       " 'bedrooms sqft_lot^2',\n",
       " 'bedrooms sqft_lot condition',\n",
       " 'bedrooms sqft_lot grade',\n",
       " 'bedrooms condition^2',\n",
       " 'bedrooms condition grade',\n",
       " 'bedrooms grade^2',\n",
       " 'bathrooms^3',\n",
       " 'bathrooms^2 sqft_living',\n",
       " 'bathrooms^2 sqft_lot',\n",
       " 'bathrooms^2 condition',\n",
       " 'bathrooms^2 grade',\n",
       " 'bathrooms sqft_living^2',\n",
       " 'bathrooms sqft_living sqft_lot',\n",
       " 'bathrooms sqft_living condition',\n",
       " 'bathrooms sqft_living grade',\n",
       " 'bathrooms sqft_lot^2',\n",
       " 'bathrooms sqft_lot condition',\n",
       " 'bathrooms sqft_lot grade',\n",
       " 'bathrooms condition^2',\n",
       " 'bathrooms condition grade',\n",
       " 'bathrooms grade^2',\n",
       " 'sqft_living^3',\n",
       " 'sqft_living^2 sqft_lot',\n",
       " 'sqft_living^2 condition',\n",
       " 'sqft_living^2 grade',\n",
       " 'sqft_living sqft_lot^2',\n",
       " 'sqft_living sqft_lot condition',\n",
       " 'sqft_living sqft_lot grade',\n",
       " 'sqft_living condition^2',\n",
       " 'sqft_living condition grade',\n",
       " 'sqft_living grade^2',\n",
       " 'sqft_lot^3',\n",
       " 'sqft_lot^2 condition',\n",
       " 'sqft_lot^2 grade',\n",
       " 'sqft_lot condition^2',\n",
       " 'sqft_lot condition grade',\n",
       " 'sqft_lot grade^2',\n",
       " 'condition^3',\n",
       " 'condition^2 grade',\n",
       " 'condition grade^2',\n",
       " 'grade^3',\n",
       " 'bedrooms^4',\n",
       " 'bedrooms^3 bathrooms',\n",
       " 'bedrooms^3 sqft_living',\n",
       " 'bedrooms^3 sqft_lot',\n",
       " 'bedrooms^3 condition',\n",
       " 'bedrooms^3 grade',\n",
       " 'bedrooms^2 bathrooms^2',\n",
       " 'bedrooms^2 bathrooms sqft_living',\n",
       " 'bedrooms^2 bathrooms sqft_lot',\n",
       " 'bedrooms^2 bathrooms condition',\n",
       " 'bedrooms^2 bathrooms grade',\n",
       " 'bedrooms^2 sqft_living^2',\n",
       " 'bedrooms^2 sqft_living sqft_lot',\n",
       " 'bedrooms^2 sqft_living condition',\n",
       " 'bedrooms^2 sqft_living grade',\n",
       " 'bedrooms^2 sqft_lot^2',\n",
       " 'bedrooms^2 sqft_lot condition',\n",
       " 'bedrooms^2 sqft_lot grade',\n",
       " 'bedrooms^2 condition^2',\n",
       " 'bedrooms^2 condition grade',\n",
       " 'bedrooms^2 grade^2',\n",
       " 'bedrooms bathrooms^3',\n",
       " 'bedrooms bathrooms^2 sqft_living',\n",
       " 'bedrooms bathrooms^2 sqft_lot',\n",
       " 'bedrooms bathrooms^2 condition',\n",
       " 'bedrooms bathrooms^2 grade',\n",
       " 'bedrooms bathrooms sqft_living^2',\n",
       " 'bedrooms bathrooms sqft_living sqft_lot',\n",
       " 'bedrooms bathrooms sqft_living condition',\n",
       " 'bedrooms bathrooms sqft_living grade',\n",
       " 'bedrooms bathrooms sqft_lot^2',\n",
       " 'bedrooms bathrooms sqft_lot condition',\n",
       " 'bedrooms bathrooms sqft_lot grade',\n",
       " 'bedrooms bathrooms condition^2',\n",
       " 'bedrooms bathrooms condition grade',\n",
       " 'bedrooms bathrooms grade^2',\n",
       " 'bedrooms sqft_living^3',\n",
       " 'bedrooms sqft_living^2 sqft_lot',\n",
       " 'bedrooms sqft_living^2 condition',\n",
       " 'bedrooms sqft_living^2 grade',\n",
       " 'bedrooms sqft_living sqft_lot^2',\n",
       " 'bedrooms sqft_living sqft_lot condition',\n",
       " 'bedrooms sqft_living sqft_lot grade',\n",
       " 'bedrooms sqft_living condition^2',\n",
       " 'bedrooms sqft_living condition grade',\n",
       " 'bedrooms sqft_living grade^2',\n",
       " 'bedrooms sqft_lot^3',\n",
       " 'bedrooms sqft_lot^2 condition',\n",
       " 'bedrooms sqft_lot^2 grade',\n",
       " 'bedrooms sqft_lot condition^2',\n",
       " 'bedrooms sqft_lot condition grade',\n",
       " 'bedrooms sqft_lot grade^2',\n",
       " 'bedrooms condition^3',\n",
       " 'bedrooms condition^2 grade',\n",
       " 'bedrooms condition grade^2',\n",
       " 'bedrooms grade^3',\n",
       " 'bathrooms^4',\n",
       " 'bathrooms^3 sqft_living',\n",
       " 'bathrooms^3 sqft_lot',\n",
       " 'bathrooms^3 condition',\n",
       " 'bathrooms^3 grade',\n",
       " 'bathrooms^2 sqft_living^2',\n",
       " 'bathrooms^2 sqft_living sqft_lot',\n",
       " 'bathrooms^2 sqft_living condition',\n",
       " 'bathrooms^2 sqft_living grade',\n",
       " 'bathrooms^2 sqft_lot^2',\n",
       " 'bathrooms^2 sqft_lot condition',\n",
       " 'bathrooms^2 sqft_lot grade',\n",
       " 'bathrooms^2 condition^2',\n",
       " 'bathrooms^2 condition grade',\n",
       " 'bathrooms^2 grade^2',\n",
       " 'bathrooms sqft_living^3',\n",
       " 'bathrooms sqft_living^2 sqft_lot',\n",
       " 'bathrooms sqft_living^2 condition',\n",
       " 'bathrooms sqft_living^2 grade',\n",
       " 'bathrooms sqft_living sqft_lot^2',\n",
       " 'bathrooms sqft_living sqft_lot condition',\n",
       " 'bathrooms sqft_living sqft_lot grade',\n",
       " 'bathrooms sqft_living condition^2',\n",
       " 'bathrooms sqft_living condition grade',\n",
       " 'bathrooms sqft_living grade^2',\n",
       " 'bathrooms sqft_lot^3',\n",
       " 'bathrooms sqft_lot^2 condition',\n",
       " 'bathrooms sqft_lot^2 grade',\n",
       " 'bathrooms sqft_lot condition^2',\n",
       " 'bathrooms sqft_lot condition grade',\n",
       " 'bathrooms sqft_lot grade^2',\n",
       " 'bathrooms condition^3',\n",
       " 'bathrooms condition^2 grade',\n",
       " 'bathrooms condition grade^2',\n",
       " 'bathrooms grade^3',\n",
       " 'sqft_living^4',\n",
       " 'sqft_living^3 sqft_lot',\n",
       " 'sqft_living^3 condition',\n",
       " 'sqft_living^3 grade',\n",
       " 'sqft_living^2 sqft_lot^2',\n",
       " 'sqft_living^2 sqft_lot condition',\n",
       " 'sqft_living^2 sqft_lot grade',\n",
       " 'sqft_living^2 condition^2',\n",
       " 'sqft_living^2 condition grade',\n",
       " 'sqft_living^2 grade^2',\n",
       " 'sqft_living sqft_lot^3',\n",
       " 'sqft_living sqft_lot^2 condition',\n",
       " 'sqft_living sqft_lot^2 grade',\n",
       " 'sqft_living sqft_lot condition^2',\n",
       " 'sqft_living sqft_lot condition grade',\n",
       " 'sqft_living sqft_lot grade^2',\n",
       " 'sqft_living condition^3',\n",
       " 'sqft_living condition^2 grade',\n",
       " 'sqft_living condition grade^2',\n",
       " 'sqft_living grade^3',\n",
       " 'sqft_lot^4',\n",
       " 'sqft_lot^3 condition',\n",
       " 'sqft_lot^3 grade',\n",
       " 'sqft_lot^2 condition^2',\n",
       " 'sqft_lot^2 condition grade',\n",
       " 'sqft_lot^2 grade^2',\n",
       " 'sqft_lot condition^3',\n",
       " 'sqft_lot condition^2 grade',\n",
       " 'sqft_lot condition grade^2',\n",
       " 'sqft_lot grade^3',\n",
       " 'condition^4',\n",
       " 'condition^3 grade',\n",
       " 'condition^2 grade^2',\n",
       " 'condition grade^3',\n",
       " 'grade^4',\n",
       " 'bedrooms^5',\n",
       " 'bedrooms^4 bathrooms',\n",
       " 'bedrooms^4 sqft_living',\n",
       " 'bedrooms^4 sqft_lot',\n",
       " 'bedrooms^4 condition',\n",
       " 'bedrooms^4 grade',\n",
       " 'bedrooms^3 bathrooms^2',\n",
       " 'bedrooms^3 bathrooms sqft_living',\n",
       " 'bedrooms^3 bathrooms sqft_lot',\n",
       " 'bedrooms^3 bathrooms condition',\n",
       " 'bedrooms^3 bathrooms grade',\n",
       " 'bedrooms^3 sqft_living^2',\n",
       " 'bedrooms^3 sqft_living sqft_lot',\n",
       " 'bedrooms^3 sqft_living condition',\n",
       " 'bedrooms^3 sqft_living grade',\n",
       " 'bedrooms^3 sqft_lot^2',\n",
       " 'bedrooms^3 sqft_lot condition',\n",
       " 'bedrooms^3 sqft_lot grade',\n",
       " 'bedrooms^3 condition^2',\n",
       " 'bedrooms^3 condition grade',\n",
       " 'bedrooms^3 grade^2',\n",
       " 'bedrooms^2 bathrooms^3',\n",
       " 'bedrooms^2 bathrooms^2 sqft_living',\n",
       " 'bedrooms^2 bathrooms^2 sqft_lot',\n",
       " 'bedrooms^2 bathrooms^2 condition',\n",
       " 'bedrooms^2 bathrooms^2 grade',\n",
       " 'bedrooms^2 bathrooms sqft_living^2',\n",
       " 'bedrooms^2 bathrooms sqft_living sqft_lot',\n",
       " 'bedrooms^2 bathrooms sqft_living condition',\n",
       " 'bedrooms^2 bathrooms sqft_living grade',\n",
       " 'bedrooms^2 bathrooms sqft_lot^2',\n",
       " 'bedrooms^2 bathrooms sqft_lot condition',\n",
       " 'bedrooms^2 bathrooms sqft_lot grade',\n",
       " 'bedrooms^2 bathrooms condition^2',\n",
       " 'bedrooms^2 bathrooms condition grade',\n",
       " 'bedrooms^2 bathrooms grade^2',\n",
       " 'bedrooms^2 sqft_living^3',\n",
       " 'bedrooms^2 sqft_living^2 sqft_lot',\n",
       " 'bedrooms^2 sqft_living^2 condition',\n",
       " 'bedrooms^2 sqft_living^2 grade',\n",
       " 'bedrooms^2 sqft_living sqft_lot^2',\n",
       " 'bedrooms^2 sqft_living sqft_lot condition',\n",
       " 'bedrooms^2 sqft_living sqft_lot grade',\n",
       " 'bedrooms^2 sqft_living condition^2',\n",
       " 'bedrooms^2 sqft_living condition grade',\n",
       " 'bedrooms^2 sqft_living grade^2',\n",
       " 'bedrooms^2 sqft_lot^3',\n",
       " 'bedrooms^2 sqft_lot^2 condition',\n",
       " 'bedrooms^2 sqft_lot^2 grade',\n",
       " 'bedrooms^2 sqft_lot condition^2',\n",
       " 'bedrooms^2 sqft_lot condition grade',\n",
       " 'bedrooms^2 sqft_lot grade^2',\n",
       " 'bedrooms^2 condition^3',\n",
       " 'bedrooms^2 condition^2 grade',\n",
       " 'bedrooms^2 condition grade^2',\n",
       " 'bedrooms^2 grade^3',\n",
       " 'bedrooms bathrooms^4',\n",
       " 'bedrooms bathrooms^3 sqft_living',\n",
       " 'bedrooms bathrooms^3 sqft_lot',\n",
       " 'bedrooms bathrooms^3 condition',\n",
       " 'bedrooms bathrooms^3 grade',\n",
       " 'bedrooms bathrooms^2 sqft_living^2',\n",
       " 'bedrooms bathrooms^2 sqft_living sqft_lot',\n",
       " 'bedrooms bathrooms^2 sqft_living condition',\n",
       " 'bedrooms bathrooms^2 sqft_living grade',\n",
       " 'bedrooms bathrooms^2 sqft_lot^2',\n",
       " 'bedrooms bathrooms^2 sqft_lot condition',\n",
       " 'bedrooms bathrooms^2 sqft_lot grade',\n",
       " 'bedrooms bathrooms^2 condition^2',\n",
       " 'bedrooms bathrooms^2 condition grade',\n",
       " 'bedrooms bathrooms^2 grade^2',\n",
       " 'bedrooms bathrooms sqft_living^3',\n",
       " 'bedrooms bathrooms sqft_living^2 sqft_lot',\n",
       " 'bedrooms bathrooms sqft_living^2 condition',\n",
       " 'bedrooms bathrooms sqft_living^2 grade',\n",
       " 'bedrooms bathrooms sqft_living sqft_lot^2',\n",
       " 'bedrooms bathrooms sqft_living sqft_lot condition',\n",
       " 'bedrooms bathrooms sqft_living sqft_lot grade',\n",
       " 'bedrooms bathrooms sqft_living condition^2',\n",
       " 'bedrooms bathrooms sqft_living condition grade',\n",
       " 'bedrooms bathrooms sqft_living grade^2',\n",
       " 'bedrooms bathrooms sqft_lot^3',\n",
       " 'bedrooms bathrooms sqft_lot^2 condition',\n",
       " 'bedrooms bathrooms sqft_lot^2 grade',\n",
       " 'bedrooms bathrooms sqft_lot condition^2',\n",
       " 'bedrooms bathrooms sqft_lot condition grade',\n",
       " 'bedrooms bathrooms sqft_lot grade^2',\n",
       " 'bedrooms bathrooms condition^3',\n",
       " 'bedrooms bathrooms condition^2 grade',\n",
       " 'bedrooms bathrooms condition grade^2',\n",
       " 'bedrooms bathrooms grade^3',\n",
       " 'bedrooms sqft_living^4',\n",
       " 'bedrooms sqft_living^3 sqft_lot',\n",
       " 'bedrooms sqft_living^3 condition',\n",
       " 'bedrooms sqft_living^3 grade',\n",
       " 'bedrooms sqft_living^2 sqft_lot^2',\n",
       " 'bedrooms sqft_living^2 sqft_lot condition',\n",
       " 'bedrooms sqft_living^2 sqft_lot grade',\n",
       " 'bedrooms sqft_living^2 condition^2',\n",
       " 'bedrooms sqft_living^2 condition grade',\n",
       " 'bedrooms sqft_living^2 grade^2',\n",
       " 'bedrooms sqft_living sqft_lot^3',\n",
       " 'bedrooms sqft_living sqft_lot^2 condition',\n",
       " 'bedrooms sqft_living sqft_lot^2 grade',\n",
       " 'bedrooms sqft_living sqft_lot condition^2',\n",
       " 'bedrooms sqft_living sqft_lot condition grade',\n",
       " 'bedrooms sqft_living sqft_lot grade^2',\n",
       " 'bedrooms sqft_living condition^3',\n",
       " 'bedrooms sqft_living condition^2 grade',\n",
       " 'bedrooms sqft_living condition grade^2',\n",
       " 'bedrooms sqft_living grade^3',\n",
       " 'bedrooms sqft_lot^4',\n",
       " 'bedrooms sqft_lot^3 condition',\n",
       " 'bedrooms sqft_lot^3 grade',\n",
       " 'bedrooms sqft_lot^2 condition^2',\n",
       " 'bedrooms sqft_lot^2 condition grade',\n",
       " 'bedrooms sqft_lot^2 grade^2',\n",
       " 'bedrooms sqft_lot condition^3',\n",
       " 'bedrooms sqft_lot condition^2 grade',\n",
       " 'bedrooms sqft_lot condition grade^2',\n",
       " 'bedrooms sqft_lot grade^3',\n",
       " 'bedrooms condition^4',\n",
       " 'bedrooms condition^3 grade',\n",
       " 'bedrooms condition^2 grade^2',\n",
       " 'bedrooms condition grade^3',\n",
       " 'bedrooms grade^4',\n",
       " 'bathrooms^5',\n",
       " 'bathrooms^4 sqft_living',\n",
       " 'bathrooms^4 sqft_lot',\n",
       " 'bathrooms^4 condition',\n",
       " 'bathrooms^4 grade',\n",
       " 'bathrooms^3 sqft_living^2',\n",
       " 'bathrooms^3 sqft_living sqft_lot',\n",
       " 'bathrooms^3 sqft_living condition',\n",
       " 'bathrooms^3 sqft_living grade',\n",
       " 'bathrooms^3 sqft_lot^2',\n",
       " 'bathrooms^3 sqft_lot condition',\n",
       " 'bathrooms^3 sqft_lot grade',\n",
       " 'bathrooms^3 condition^2',\n",
       " 'bathrooms^3 condition grade',\n",
       " 'bathrooms^3 grade^2',\n",
       " 'bathrooms^2 sqft_living^3',\n",
       " 'bathrooms^2 sqft_living^2 sqft_lot',\n",
       " 'bathrooms^2 sqft_living^2 condition',\n",
       " 'bathrooms^2 sqft_living^2 grade',\n",
       " 'bathrooms^2 sqft_living sqft_lot^2',\n",
       " 'bathrooms^2 sqft_living sqft_lot condition',\n",
       " 'bathrooms^2 sqft_living sqft_lot grade',\n",
       " 'bathrooms^2 sqft_living condition^2',\n",
       " 'bathrooms^2 sqft_living condition grade',\n",
       " 'bathrooms^2 sqft_living grade^2',\n",
       " 'bathrooms^2 sqft_lot^3',\n",
       " 'bathrooms^2 sqft_lot^2 condition',\n",
       " 'bathrooms^2 sqft_lot^2 grade',\n",
       " 'bathrooms^2 sqft_lot condition^2',\n",
       " 'bathrooms^2 sqft_lot condition grade',\n",
       " 'bathrooms^2 sqft_lot grade^2',\n",
       " 'bathrooms^2 condition^3',\n",
       " 'bathrooms^2 condition^2 grade',\n",
       " 'bathrooms^2 condition grade^2',\n",
       " 'bathrooms^2 grade^3',\n",
       " 'bathrooms sqft_living^4',\n",
       " 'bathrooms sqft_living^3 sqft_lot',\n",
       " 'bathrooms sqft_living^3 condition',\n",
       " 'bathrooms sqft_living^3 grade',\n",
       " 'bathrooms sqft_living^2 sqft_lot^2',\n",
       " 'bathrooms sqft_living^2 sqft_lot condition',\n",
       " 'bathrooms sqft_living^2 sqft_lot grade',\n",
       " 'bathrooms sqft_living^2 condition^2',\n",
       " 'bathrooms sqft_living^2 condition grade',\n",
       " 'bathrooms sqft_living^2 grade^2',\n",
       " 'bathrooms sqft_living sqft_lot^3',\n",
       " 'bathrooms sqft_living sqft_lot^2 condition',\n",
       " 'bathrooms sqft_living sqft_lot^2 grade',\n",
       " 'bathrooms sqft_living sqft_lot condition^2',\n",
       " 'bathrooms sqft_living sqft_lot condition grade',\n",
       " 'bathrooms sqft_living sqft_lot grade^2',\n",
       " 'bathrooms sqft_living condition^3',\n",
       " 'bathrooms sqft_living condition^2 grade',\n",
       " 'bathrooms sqft_living condition grade^2',\n",
       " 'bathrooms sqft_living grade^3',\n",
       " 'bathrooms sqft_lot^4',\n",
       " 'bathrooms sqft_lot^3 condition',\n",
       " 'bathrooms sqft_lot^3 grade',\n",
       " 'bathrooms sqft_lot^2 condition^2',\n",
       " 'bathrooms sqft_lot^2 condition grade',\n",
       " 'bathrooms sqft_lot^2 grade^2',\n",
       " 'bathrooms sqft_lot condition^3',\n",
       " 'bathrooms sqft_lot condition^2 grade',\n",
       " 'bathrooms sqft_lot condition grade^2',\n",
       " 'bathrooms sqft_lot grade^3',\n",
       " 'bathrooms condition^4',\n",
       " 'bathrooms condition^3 grade',\n",
       " 'bathrooms condition^2 grade^2',\n",
       " 'bathrooms condition grade^3',\n",
       " 'bathrooms grade^4',\n",
       " 'sqft_living^5',\n",
       " 'sqft_living^4 sqft_lot',\n",
       " 'sqft_living^4 condition',\n",
       " 'sqft_living^4 grade',\n",
       " 'sqft_living^3 sqft_lot^2',\n",
       " 'sqft_living^3 sqft_lot condition',\n",
       " 'sqft_living^3 sqft_lot grade',\n",
       " 'sqft_living^3 condition^2',\n",
       " 'sqft_living^3 condition grade',\n",
       " 'sqft_living^3 grade^2',\n",
       " 'sqft_living^2 sqft_lot^3',\n",
       " 'sqft_living^2 sqft_lot^2 condition',\n",
       " 'sqft_living^2 sqft_lot^2 grade',\n",
       " 'sqft_living^2 sqft_lot condition^2',\n",
       " 'sqft_living^2 sqft_lot condition grade',\n",
       " 'sqft_living^2 sqft_lot grade^2',\n",
       " 'sqft_living^2 condition^3',\n",
       " 'sqft_living^2 condition^2 grade',\n",
       " 'sqft_living^2 condition grade^2',\n",
       " 'sqft_living^2 grade^3',\n",
       " 'sqft_living sqft_lot^4',\n",
       " 'sqft_living sqft_lot^3 condition',\n",
       " 'sqft_living sqft_lot^3 grade',\n",
       " 'sqft_living sqft_lot^2 condition^2',\n",
       " 'sqft_living sqft_lot^2 condition grade',\n",
       " 'sqft_living sqft_lot^2 grade^2',\n",
       " 'sqft_living sqft_lot condition^3',\n",
       " 'sqft_living sqft_lot condition^2 grade',\n",
       " 'sqft_living sqft_lot condition grade^2',\n",
       " 'sqft_living sqft_lot grade^3',\n",
       " 'sqft_living condition^4',\n",
       " 'sqft_living condition^3 grade',\n",
       " 'sqft_living condition^2 grade^2',\n",
       " 'sqft_living condition grade^3',\n",
       " 'sqft_living grade^4',\n",
       " 'sqft_lot^5',\n",
       " 'sqft_lot^4 condition',\n",
       " 'sqft_lot^4 grade',\n",
       " 'sqft_lot^3 condition^2',\n",
       " 'sqft_lot^3 condition grade',\n",
       " 'sqft_lot^3 grade^2',\n",
       " 'sqft_lot^2 condition^3',\n",
       " 'sqft_lot^2 condition^2 grade',\n",
       " 'sqft_lot^2 condition grade^2',\n",
       " 'sqft_lot^2 grade^3',\n",
       " 'sqft_lot condition^4',\n",
       " 'sqft_lot condition^3 grade',\n",
       " 'sqft_lot condition^2 grade^2',\n",
       " 'sqft_lot condition grade^3',\n",
       " 'sqft_lot grade^4',\n",
       " 'condition^5',\n",
       " 'condition^4 grade',\n",
       " 'condition^3 grade^2',\n",
       " 'condition^2 grade^3',\n",
       " 'condition grade^4',\n",
       " 'grade^5']"
      ]
     },
     "execution_count": 107,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pf = PolynomialFeatures(degree=5)\n",
    "pf.fit(house_training_data[p2_features])\n",
    "feature_names = pf.get_feature_names(p2_features)\n",
    "feature_names"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "For example, the first coefficient is approximately \\$453,000, which is the intercept term for our model.\n",
    "\n",
    "The second and third coefficients are 0, which correspond to the weight of our \"bedrooms\" feature and \"bathrooms\" feature. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Challenge: Create a table of all the features and their weights. Only include features with non-zero weight."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>weight</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>453576.617822</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>bedrooms</td>\n",
       "      <td>-0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>bathrooms</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>sqft_living</td>\n",
       "      <td>70714.920065</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>sqft_lot</td>\n",
       "      <td>-0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>condition</td>\n",
       "      <td>4977.722890</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>grade</td>\n",
       "      <td>90144.876211</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>bedrooms^2</td>\n",
       "      <td>6988.727188</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>bedrooms bathrooms</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>bedrooms sqft_living</td>\n",
       "      <td>0.000000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                   name         weight\n",
       "0                     1  453576.617822\n",
       "1              bedrooms      -0.000000\n",
       "2             bathrooms       0.000000\n",
       "3           sqft_living   70714.920065\n",
       "4              sqft_lot      -0.000000\n",
       "5             condition    4977.722890\n",
       "6                 grade   90144.876211\n",
       "7            bedrooms^2    6988.727188\n",
       "8    bedrooms bathrooms       0.000000\n",
       "9  bedrooms sqft_living       0.000000"
      ]
     },
     "execution_count": 109,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "feature_table = pd.DataFrame({\n",
    "    'name': feature_names,\n",
    "    'weight': p2h_model.named_steps['model'].coef_\n",
    "})\n",
    "feature_table.head(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>weight</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>453576.617822</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>grade</td>\n",
       "      <td>90144.876211</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>sqft_living</td>\n",
       "      <td>70714.920065</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>27</th>\n",
       "      <td>grade^2</td>\n",
       "      <td>21819.120976</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>bathrooms^2</td>\n",
       "      <td>12128.591597</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>201</th>\n",
       "      <td>sqft_lot condition^3</td>\n",
       "      <td>-1052.785978</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>419</th>\n",
       "      <td>sqft_living^2 sqft_lot condition^2</td>\n",
       "      <td>-1141.980869</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>454</th>\n",
       "      <td>sqft_lot condition grade^3</td>\n",
       "      <td>-1268.756693</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>204</th>\n",
       "      <td>sqft_lot grade^3</td>\n",
       "      <td>-2518.116798</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>176</th>\n",
       "      <td>sqft_living^3 sqft_lot</td>\n",
       "      <td>-3058.331095</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>111 rows × 2 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "                                   name         weight\n",
       "0                                     1  453576.617822\n",
       "6                                 grade   90144.876211\n",
       "3                           sqft_living   70714.920065\n",
       "27                              grade^2   21819.120976\n",
       "13                          bathrooms^2   12128.591597\n",
       "..                                  ...            ...\n",
       "201                sqft_lot condition^3   -1052.785978\n",
       "419  sqft_living^2 sqft_lot condition^2   -1141.980869\n",
       "454          sqft_lot condition grade^3   -1268.756693\n",
       "204                    sqft_lot grade^3   -2518.116798\n",
       "176              sqft_living^3 sqft_lot   -3058.331095\n",
       "\n",
       "[111 rows x 2 columns]"
      ]
     },
     "execution_count": 110,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "feature_table[abs(feature_table['weight']) > 10**-2].sort_values(\n",
    "    'weight', ascending=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "462"
      ]
     },
     "execution_count": 111,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(feature_names)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
